package com.sky.service.impl;

import com.sky.dto.GoodsSalesDTO;
import com.sky.dto.ReportUserStatisticsDTO;
import com.sky.mapper.ReportMapper;
import com.sky.service.ReportService;
import com.sky.service.WorksPaceService;
import com.sky.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * @author yangkexuan
 * @className ReportServiceImpl
 * @date 2023/6/16 14:43
 * @description
 */
@Slf4j
@Service
public class ReportServiceImpl implements ReportService {
    @Autowired
    private ReportMapper reportMapper;

    @Autowired
    private WorksPaceService worksPaceService;

    /**
     * 导出Ecele报表接口
     */
    @Override
    public void export(HttpServletResponse response) {
        LocalDate begin = LocalDate.now().minusDays(30);
        LocalDate end = LocalDate.now().minusDays(1);
        //查询概览运营数据，提供给Excel模板文件
        BusinessDataVO businessData = worksPaceService.businessData(LocalDateTime.of(begin,LocalTime.MIN), LocalDateTime.of(end, LocalTime.MAX));
        InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("template/运营数据报表模板.xlsx");
        try {
            //基于提供好的模板文件创建一个新的Excel表格对象
            XSSFWorkbook excel = new XSSFWorkbook(inputStream);
            //获得Excel文件中的一个Sheet页
            XSSFSheet sheet = excel.getSheet("Sheet1");

            sheet.getRow(1).getCell(1).setCellValue(begin + "至" + end);
            //获得第4行
            XSSFRow row = sheet.getRow(3);
            //获取单元格
            row.getCell(2).setCellValue(businessData.getTurnover());
            row.getCell(4).setCellValue(businessData.getOrderCompletionRate());
            row.getCell(6).setCellValue(businessData.getNewUsers());
            row = sheet.getRow(4);
            row.getCell(2).setCellValue(businessData.getValidOrderCount());
            row.getCell(4).setCellValue(businessData.getUnitPrice());
            for (int i = 0; i < 30; i++) {
                LocalDate date = begin.plusDays(i);
                //准备明细数据
                businessData = worksPaceService.businessData(LocalDateTime.of(date,LocalTime.MIN), LocalDateTime.of(date, LocalTime.MAX));
                row = sheet.getRow(7 + i);
                row.getCell(1).setCellValue(date.toString());
                row.getCell(2).setCellValue(businessData.getTurnover());
                row.getCell(3).setCellValue(businessData.getValidOrderCount());
                row.getCell(4).setCellValue(businessData.getOrderCompletionRate());
                row.getCell(5).setCellValue(businessData.getUnitPrice());
                row.getCell(6).setCellValue(businessData.getNewUsers());
            }
            //通过输出流将文件下载到客户端浏览器中
            ServletOutputStream out = response.getOutputStream();
            excel.write(out);
            //关闭资源
            out.flush();
            out.close();
            excel.close();

        }catch (IOException e){
            e.printStackTrace();
        }

    }

    /**
     * 查询销量排名top10接口
     *
     * @param begin
     * @param end
     * @return
     */
    @Override
    public SalesTop10ReportVO top10(LocalDate begin, LocalDate end) {
        List<GoodsSalesDTO> list = reportMapper.selectTop10(begin.atStartOfDay(),end.atStartOfDay());
        // 将查询出的内容分别遍历出然后拼接成一个字符串
        String names = list.stream().map(GoodsSalesDTO::getName).collect(Collectors.joining(", "));
        String numbers = list.stream().map(dto -> Integer.toString(dto.getNumber())).collect(Collectors.joining(", "));

        SalesTop10ReportVO sales = new SalesTop10ReportVO();
        sales.setNameList(names);
        sales.setNumberList(numbers);
        return sales;
    }

    /**
     * 用户统计接口
     *
     * @param begin
     * @param end
     * @return
     */
    @Override
    public UserReportVO userStatistics(LocalDate begin, LocalDate end) {

        List<ReportUserStatisticsDTO> list = reportMapper.userStatistics(begin.atStartOfDay(),end.atStartOfDay());

        // 日期 拼接成String
        String dateList =list.stream().map(ReportUserStatisticsDTO::getDate).collect(Collectors.joining(", "));
        // 新增用户 拼接成String
        String newUserList = list.stream().map(dto -> Integer.toString(dto.getNewUser())).collect(Collectors.joining(", "));
        // 用户总量 将list里的新增用户提溜到新列表中
        List<Integer> total = list.stream().map(ReportUserStatisticsDTO::getNewUser).collect(Collectors.toList());
        //计算总用户量，第2天的总用户量 = 第一天的新增+ 第二天的新增
        // IntStream:提供了一系列操作int类型数据流的方法，包括生成、转换、操作和消费等等
        // .orElse() Optional类提供的来处理值为null的情况，如果Optional对象中的值不为null，则返回该值，否则返回指定的默认值
        List<Integer> totalNum = IntStream.range(0, total.size())
                .mapToObj(i -> total.stream().limit(i+1).reduce(Integer::sum).orElse(0))
                .collect(Collectors.toList());
        //拼接成String
        String totalNumStr = totalNum.stream().map(Object::toString).collect(Collectors.joining(","));

        UserReportVO reportVO = new UserReportVO();
        reportVO.setDateList(dateList).setNewUserList(newUserList).setTotalUserList(totalNumStr);
        return reportVO;
    }

    /**
     * 营业额统计接口
     *
     * @param begin
     * @param end
     * @return
     */
    @Override
    public TurnoverReportVO turnoverStatistics(LocalDate begin, LocalDate end) {
        List<ReportUserStatisticsDTO> list = reportMapper.turnoverStatistics(begin.atStartOfDay(),end.atStartOfDay());
        String dateList =list.stream().map(ReportUserStatisticsDTO::getDate).collect(Collectors.joining(", "));
        // 新增用户 拼接成String
        String turnoverList = list.stream().map(dto -> Integer.toString(dto.getNewUser())).collect(Collectors.joining(", "));

        TurnoverReportVO turnoverReportVO = new TurnoverReportVO();
        turnoverReportVO.setDateList(dateList).setTurnoverList(turnoverList);
        return turnoverReportVO;
    }

    /**
     * 订单统计接口
     *
     * @param begin
     * @param end
     * @return
     */
    @Override
    public OrderReportVO ordersStatistics(LocalDate begin, LocalDate end) {
        //获取订单总数，有效订单,订单完成率
        OrderReportVO orderReportVO = reportMapper.ordersStatistics(begin.atStartOfDay(),end.atStartOfDay());
        Double orderCompletionRate = (double)orderReportVO.getValidOrderCount() / orderReportVO.getTotalOrderCount();
        orderReportVO.setOrderCompletionRate(orderCompletionRate);

        //获取 每日订单数 每日有效订单数 订单率
        List<OrderReportDayVO> list = reportMapper.ordersStatisticsDay(begin.atStartOfDay(),end.atStartOfDay());
         String dateList = list.stream().map(OrderReportDayVO::getDateList).collect(Collectors.joining(","));
         String orderCountList = list.stream().map(OrderReportDayVO::getOrderCountList).collect(Collectors.joining(","));
         //每日有效订单数，以逗号分隔，例如：20,21,10
         String validOrderCountList = list.stream().map(OrderReportDayVO::getValidOrderCountList).collect(Collectors.joining(","));
        orderReportVO.setDateList(dateList).setOrderCountList(orderCountList).setValidOrderCountList(validOrderCountList);
        return orderReportVO;
    }
}
